C#进阶(上) Aholic~茜 2025-06-07 2025-07-16 本篇章内容知识偏多,因此分三次上传。
简单数据结构类 ArrayList ArrayList的本质 ArrayList是一个C#为我们1封装好的的类,本质是一个object类型的数组,ArrayList类帮助我们实现很多方法,比如数组的删减查改。
申明 1 2 using System.CollectionsArrayList array = new ArrayList();
增删查改 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 array.Add(1 ); array.AddRange(array2); array.Remove(1 ); array.Insert(1 ,"1234567" ); array.RemoveAt(2 ) array.Clear(); arrary[0 ]; if (array.Contains("bababoi" )){ } int idx;idx = array.IndexOf(true ); idx = array.LastIndexOf(true ); array[0 ] = "999" ;
遍历 1 2 3 4 5 6 7 8 9 10 11 12 13 int l = array.Count;int r = array.Capacity;for (int i = 0 ; i < l; i++){ Console.WriteLine(array[i]); } foreach (var item in array){ Console.WriteLine(item); }
装箱拆箱 ArrayList本质是一个可以自动扩容的object数组,由于万物之父用来储存数据,自然存在装箱拆箱。所以ArrayList尽量少用,后期会有一个更好的数据容器。
Stack Stack的本质 Stack是一个c#封装好的类,它的本质是object数组,只是封装了特殊的存储规则。 Stack是栈存储容器,栈是一种先进后出的数据结构。可以类似看作是一个水桶。
申明 1 2 using System.Collections;Stack stack = new Stack();
增取查改 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 stack.Push(1 ); object v = stack.Pop();stack.Pop(); v = stack.Peek(); if (stack.Contains(1 )){ } stack.Clear();
遍历 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 int l = stack.Count;foreach (object item in stack){ Console.WriteLine(item); } object [] array = stack.ToArray();for (int i = 0 ; i < l; i++){ Console.WriteLine(array[i]); } while (stack.Count > 0 ){ object o = stack.Pop(); Console.WriteLine(o); }
装箱拆箱 与ArrayList一致。
Queue Queue本质 Queue是一个c#封装好的类,它的本质是object数组,只是封装了特殊的存储规则。 Queue是队列存储容器,队列是一种先进先出、后进后出的数据结构。可以类似看作是一个通道。
申明 1 2 using System.Collections;Queue queue = new Queue();
增取查改 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 queue.Enqueue(1 ); object v = queue.Dequeue();queue Dequeue () ;v = queue.Peek(); if (queue.Contains(1 )){ }
遍历 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 int l = queue.Count;foreach (object item in queuue){ } object [] array = queue.ToArray();for (int i = 0 ; i < l; i++){ } while (queue.Count > 0 ){ object o = queue.Dequeue(); }
装箱拆箱 与栈一致。
Hashtable Hashtable的本质 又称散列表,是基于键的哈希代码组织起来的键/值对,它的主要作用是提高数据查询的效率,使用键来访问集合中的元素。
申明 1 2 using System.Collections;Hashtable hashtable = new Hashtable();
增删查改 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 hashtable.Add(1 , "123" ); hashtable.Remove(1 ); hashtable.Clear(); hashtable[1 ]; if (hashtable.Contains(1 )){ } if (hashtable.ContainsKey(1 )){ } if (hashtable.ContainsValuue("123" )){ } hashtable[1 ] = "321" ;
遍历 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 int l = hashtable.Count;foreach (object item in hashtable.Keys){ } foreach (object item in hashtable.Values){ } foreach (DictionaryEntry item in hashtable){ Console.WriteLine(item.Key + item.Value); } IDictionaryEnumerator myEnumerator = hashtable.GetEnumerator(); bool flag = myEnumerator.MoveNext();while (flag){ Console.WriteLine(myEnumerator.Key + myEnumerator.Value); flag = myEnumerator.MoveNext(); }
装箱拆箱 与前面的一样。
泛型 泛型 是什么 泛型实现了类型参数化,达到代码重用的目的,通过类型参数化来实现同一份代码上操作多种类型。 泛型相当于类型占位符,定义类或方法时使用替代符代表变量类型,当真正使用类或方法时再具体指定类型。
泛型分类 泛型类和泛型接口:
1 2 class 类名<泛型占位字母>interface 接口名<泛型占位字母>
泛型函数
泛型占位字母可以有多个,用逗号隔开。
泛型类和接口 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 class TestClass <T >{ public T value ; } TestClass<int > t = new TestClass<int >(); t.value = 10 ; TestClass<string > t2 = new TestClass<int >(); t2.value = "1100" ; class Test <T , K , L >{ public T value1; public K value2; public L value3; } Test<int , string , bool > t3 = new Test<int , string , bool >();
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 interface Test <T >{ T Value { get ; set ; } } class Test : TestInterface <int >{ public int Value { get ; set ; } }
泛型方法 普通类中的泛型方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 class Test2 { public void TestFun <T >( T value ) { } public void TestFun <T >() { T t = default (T); } public T TestFun <T >(string v ) { T t = default (T); return t; } } Test2 tt = new Test2(); tt.TestFun<string >("123" );
泛型类中的泛型方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 class Test2 <T >{ public T value ; public void TestFun <M >(M m ) { } public void TestFun (T t ) { } } Test2<int > tt = new Test2<int >(); tt.TestFun(10 ); tt.TestFun<string >("123" );
泛型作用
不同类型对象的相同逻辑处理可以使用泛型
使用泛型可以有效避免装箱拆箱
例如:
1 2 3 4 5 6 7 8 9 10 11 12 class ArrayList <T >{ private T[] array; public void Add (T value ) { } public void Remove (T value ) { } }
泛型约束 什么是泛型约束 让泛型的类型有一定的限制,关键字:where;泛型约束有6种:
值类型: where 泛型字母:struct
引用类型: where 泛型字母: class
存在无参公共构造函数: where 泛型字母:new()
某个类本身或者其派生类(某个接口的派生类型): where 泛型字母:接口名
另一个泛型类型本身或者派生类型: where 泛型字母:另一个泛型字母
各个泛型类型的解释 值类型约束
1 2 3 4 5 6 7 8 class Test1 <T > where T : struct { public T value ; public void TestFun <K >(K v ) where K : struct { } }
引用类型约束
1 2 3 4 5 6 7 8 class Test2 <T > where T : class { public T value ; public void TestFun <K >(K v ) where K : class { } }
无参公共构造函数约束
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 class Text3 <T > where T : new (){ public T value ; public void TestFun <K >(K v ) where K : new () { } } class Test1 { } class Test2 { public void Test2 (int a ) { } } Test3<Test1> t3 = new Test3<Test1>();
类约束:必须是该类或者其派生类
1 2 3 4 5 6 7 8 class Text4 <T > where T : Test1 { public T value ; public void TestFun <K >(K v ) where K : Test1 { } }
接口约束:接口的派生类型
1 2 3 4 5 6 7 8 9 10 11 12 interface IFly { } class Text5 <T > where T : IFly { public T value ; public void TestFun <K >(K v ) where K : IFly { } }
另一个泛型类型约束
1 2 3 4 5 6 7 8 class Test6 <V ,U > where : V : U { ppublic V value ; public void TestFun <T ,K >(K k ) where K : T { } }
多个泛型有约束 同一种泛型多约束加逗号。不同泛型直接写where
1 2 3 4 class Test8 <T ,K > where T : class , new () where K : struct { }
常用泛型数据结构类 List List的本质 List是c#为我们封装好的额一个类,它的本质是一个可变类型的泛型数组,List类为我们实现很多方法,比如泛型数组的增删查改。
申明 1 2 using System.Collections.Generic;List<int > list = new Lies<int >();
增删查改 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 list.Add(1 ); list.AddRange(); list.Insert(0 , 999 ); list.Remove(1 ); list.RemoveAt(0 ); list.Clear(); int i = list[0 ];if (list.Contains(1 )){ } int idx = list.IndexOf(1 );int idx2 = list.LastIndexOf(1 );list[0 ] = 2 ;
遍历 1 2 3 4 5 6 7 8 9 int l = list.Count;for (int i 0 ; i < l; i++){ Console.WriteLine(list[i]); } foreach (int item in list){ Console.WriteLine(item); }
Dictionarry Dictionary的本质 可以将Dictionary理解成拥有泛型的Hashtable,它是基于键的哈希代码组织起来的键值对,键值对类型从Hashtable的object变为了可以自己定制的泛型。
申明 1 2 3 using System.Collections.GenericDictionary<int ,string > dictionary = new Dictionary<int ,string >();
增删查改 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 dictionary.Add(1 ,"123" ); dictionary.Remove(1 ); dictionary.Clear(); string s = dictionary[1 ];if (dictionary.ContainsKey(1 )){ } if (dictionary.ContainsValue("123" )){ } dictionary[1 ] = "567" ;
遍历 1 2 3 4 5 6 7 8 9 10 11 12 13 14 int l = dictionary.Count;foreach (int item in dictionary.Count){ Console.WriteLine(item); Console.WriteLine(dictionary[item]); } foreach (string item in dictionary.Values){ Console.WriteLine(item); } for (KeyValuePair<int , string > item in dictionary){ Console.WriteLine(item.Key + ":" item.Value); }
顺序存储和链式存储 数据结构 数据结构是计算机存储、组织数据的方法,数据结构是指相互之间存在一种或多种特定关系的数据元素的集合。比如自定义一个类也可以成为一种数据结构,自己定义的数据结构组合规则。
线性表 线性表是一种数据结构,是由n个具有相同的特征的数据元素的有限序列。
顺序存储 数组、Stack,Queue,List,ArrayList都是顺序存储,只是组织规律不同罢了。 顺序存储:用一组地址连续的存储单元依次存储线性表的各个元素。
链式存储 单向链表、双向链表、循环链表 链式存储:用一组任意的存储单元存储线性表中的各个元素。
实现单向链表 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 class LinkedNode <T >{ public T value ; public LinkedNode<T> nextNode; public LinkedNode (T value ) { this value = value ; } } class LinkedList <T >{ public LinkedNode<T> head; public LinkedNode<T> last; public void Add (T value ) { LinkNode<T> node = new LinkedNode<T>(value ); } if (head == null ) { head = node; last = node; } else { last.nextNode = node; last = node; } public void Remove (T value ) { if (head == null ) { return ; } if (head.value .Equals(value )) { head = head.nextNode; if (head == null ) { last = null ; } return ; } LinkedNode<T> node = head; while (node.nextNode !!= null ) { if (node.nextNode.value .Equals(value )) { node.nextNode = node.nextNode.nextNode; break ; } } } }
顺序存储和链式存储的优缺点 从增删查改来思考
增:链式存储计算上优于顺序存储;中间插入不用移动位置
删:链式存储计算上优于顺序存储;中间插入不用移动位置
查:顺序存储使用上优于链式存储;链式只能遍历,顺序可以下标直接表示
改:顺序存储使用上优于链式存储;链式只能遍历,顺序可以下标直接表示
LinkedList LinkedList是什么 是c#为我们封装好的类,本质是一个可变类型的泛型双向链表
申明 1 2 using System.Collections.GenericLinkedList<int > link = new LinkedList<int >();
增删查改 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 link.AddLast(10 ); link.AddFirst(20 ); link.RemoveFirst(); link.RemoveLast(); link.Remove(20 ); link.Clear(); LinkListNode<int > first = link.First; LinkListNode<int > last = link.Last; LinkListNode<int > node = link.Find(10 ); LinkListNode<int > n = link.Find(20 ); link.AddAfter(n,15 ); link.AddBefore(n,11 ); if (link.Contains(10 )){ } link.First.Value = 11 ;
遍历 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 foreach (int item in link){ Console.WriteLine(item); } LinkListNode<int > now = LinkList.First while (now != null ){ now = now.Next; } LinkListNode<int > now = LinkList.Last while (now != null ){ now = now.Previous; }
泛型栈和队列 使用起来没什么不一样,
1 2 Stack<int > stack = new Stack<int >(); Queue<int > queue = new Queue<int >();